<template>
  <!-- Instructions Stage -->
  <div v-if="stage === 'instructions'" class="max-w-2xl mx-auto">
    <transition appear name="fade">
      <Card class="bg-white/90 backdrop-blur-sm border-indigo-200 shadow-lg">
        <CardHeader class="text-center pb-8">
          <div
            class="w-16 h-16 bg-gradient-to-br from-indigo-500 to-purple-500 rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
            <Volume2 class="w-8 h-8 text-white"/>
          </div>
          <CardTitle class="text-2xl text-slate-800">{{ t('audioMemoryTest.title') }}</CardTitle>
          <p class="text-slate-600 mt-2">{{ t('audioMemoryTest.description') }}</p>
        </CardHeader>
        <CardContent class="space-y-6">
          <div class="bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl p-6 border border-indigo-100">
            <h3 class="font-semibold text-indigo-900 mb-4 flex items-center gap-2">
              <Star class="w-5 h-5"/>
              {{ t('audioMemoryTest.instructionsTitle') }}
            </h3>
            <div class="space-y-3 text-slate-700">
              <div class="flex gap-3"><span class="step-number">1</span>
                <p>{{ t('audioMemoryTest.instruction1') }}</p></div>
              <div class="flex gap-3"><span class="step-number">2</span>
                <p><strong>{{ t('audioMemoryTest.instruction2Important') }}</strong>{{ t('audioMemoryTest.instruction2') }}</p></div>
              <div class="flex gap-3"><span class="step-number">3</span>
                <p>{{ t('audioMemoryTest.instruction3') }}</p></div>
              <div class="flex gap-3"><span class="step-number">4</span>
                <p>{{ t('audioMemoryTest.instruction4') }}</p></div>
              <div class="flex gap-3"><span class="step-number">5</span>
                <p>{{ t('audioMemoryTest.instruction5') }}</p></div>
            </div>
          </div>
          <div class="bg-amber-50 border border-amber-200 rounded-xl p-4">
            <div class="flex items-start gap-3">
              <Volume2 class="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5"/>
              <div class="text-amber-800">
                <p class="font-semibold">{{ t('audioMemoryTest.notesTitle') }}</p>
                <p class="text-sm mt-1">{{ t('audioMemoryTest.notesDescription') }}</p>
              </div>
            </div>
          </div>
          <div class="grid md:grid-cols-3 gap-4">
            <div class="info-box">
              <div class="info-box-title text-indigo-600">10</div>
              <div class="info-box-body">{{ t('audioMemoryTest.maxLevel') }}</div>
            </div>
            <div class="info-box">
              <div class="info-box-title text-purple-600">3</div>
              <div class="info-box-body">{{ t('audioMemoryTest.errorChances') }}</div>
            </div>
            <div class="info-box">
              <div class="info-box-title text-slate-600">7</div>
              <div class="info-box-body">{{ t('audioMemoryTest.noteTypes') }}</div>
            </div>
          </div>
          <Button class="w-full bg-gradient-to-r from-indigo-500 to-purple-500 hover:from-indigo-600 hover:to-purple-600 text-white py-3 text-lg font-semibold shadow-lg hover:shadow-xl transition-all duration-200"
                  size="lg"
                  @click="handleStartFamiliarize">
            {{ t('audioMemoryTest.startFamiliarize') }}
          </Button>
        </CardContent>
      </Card>
    </transition>
  </div>

  <!-- Familiarize Stage -->
  <div v-else-if="stage === 'familiarize'" class="max-w-4xl mx-auto space-y-6">
    <div class="flex flex-col sm:flex-row gap-4 items-center justify-between">
      <div class="flex items-center gap-4">
        <Badge class="bg-indigo-100 text-indigo-700 border-indigo-300" variant="outline">{{ t('audioMemoryTest.familiarizePhase') }}</Badge>
        <div class="flex items-center gap-2 text-slate-600">
          <Volume2 class="w-4 h-4"/>
          <span class="font-semibold">{{ familiarizeClicks }} {{ t('audioMemoryTest.clicks') }}</span></div>
      </div>
      <Badge v-if="canStartTest" class="bg-green-100 text-green-700 border-green-300">
        <CheckCircle class="w-3 h-3 mr-1"/>
        {{ t('audioMemoryTest.canStartTest') }}
      </Badge>
      <Badge v-else class="bg-amber-100 text-amber-700 border-amber-300" variant="outline">{{ t('audioMemoryTest.stillNeed') }}
        {{ MIN_FAMILIARIZE_CLICKS - familiarizeClicks }} {{ t('audioMemoryTest.clicks') }}
      </Badge>
    </div>
    <div class="bg-white rounded-lg p-4 border border-slate-200">
      <div class="flex justify-between items-center mb-2">
        <span class="text-sm text-slate-600">{{ t('audioMemoryTest.familiarizeProgress') }}</span>
        <span class="text-sm font-semibold text-slate-800">{{ familiarizeProgress }}%</span>
      </div>
      <Progress :model-value="familiarizeProgress" class="h-2"/>
    </div>
    <Card class="bg-white/90 backdrop-blur-sm border-indigo-200 shadow-lg">
      <CardHeader>
        <CardTitle class="text-center">{{ t('audioMemoryTest.clickToFamiliarize') }}</CardTitle>
        <p class="text-center text-slate-600 text-sm">{{ t('audioMemoryTest.listenCarefully') }}</p>
      </CardHeader>
      <CardContent>
        <div class="grid grid-cols-4 md:grid-cols-7 gap-4 max-w-2xl mx-auto">
          <div v-for="tone in AUDIO_TONES" :key="tone.id">
            <Button :class="['w-16 h-16 rounded-full hover:opacity-80 text-white font-semibold shadow-lg transition-all duration-200', tone.color]" :disabled="isPlaying"
                    @click="handleFamiliarizeToneClick(tone)">
              {{ tone.name }}
            </Button>
          </div>
        </div>
        <div v-if="audioError" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
          <div class="flex items-center gap-2">
            <VolumeX class="w-4 h-4 text-red-600"/>
            <span class="text-red-800 text-sm">{{ t('audioMemoryTest.audioInitFailed') }}</span></div>
        </div>
        <div v-if="canStartTest" class="mt-6 text-center">
          <Button class="bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white px-8 py-2"
                  @click="handleReadyCheck">
            {{ t('audioMemoryTest.readyForTest') }}
          </Button>
        </div>
      </CardContent>
    </Card>
  </div>

  <!-- Ready Check Stage -->
  <div v-else-if="stage === 'ready-check'" class="max-w-2xl mx-auto">
    <transition appear name="fade">
      <Card class="bg-white/90 backdrop-blur-sm border-green-200 shadow-lg">
        <CardHeader class="text-center pb-8">
          <div
            class="w-16 h-16 bg-gradient-to-br from-green-500 to-emerald-500 rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
            <CheckCircle class="w-8 h-8 text-white"/>
          </div>
          <CardTitle class="text-2xl text-slate-800">{{ t('audioMemoryTest.readyToStartTest') }}</CardTitle>
          <p class="text-slate-600 mt-2">{{ t('audioMemoryTest.familiarWithNotes') }}</p>
        </CardHeader>
        <CardContent class="space-y-6">
          <div class="bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl p-6 border border-green-100">
            <h3 class="font-semibold text-green-900 mb-4 flex items-center gap-2">
              <Volume2 class="w-5 h-5"/>
              {{ t('audioMemoryTest.testReminder') }}
            </h3>
            <div class="space-y-3 text-slate-700">
              <div class="flex gap-3"><span class="step-number bg-green-500">1</span>
                <p>{{ t('audioMemoryTest.testReminder1') }}<strong>{{ t('audioMemoryTest.noVisualCues') }}</strong>{{ t('audioMemoryTest.testReminder2') }}</p></div>
              <div class="flex gap-3"><span class="step-number bg-green-500">2</span>
                <p>{{ t('audioMemoryTest.testReminder3') }}</p></div>
              <div class="flex gap-3"><span class="step-number bg-green-500">3</span>
                <p>{{ t('audioMemoryTest.testReminder4') }}</p></div>
              <div class="flex gap-3"><span class="step-number bg-green-500">4</span>
                <p>{{ t('audioMemoryTest.testReminder5') }}</p></div>
            </div>
          </div>
          <div class="bg-red-50 border border-red-200 rounded-xl p-4">
            <div class="flex items-start gap-3">
              <VolumeX class="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5"/>
              <div class="text-red-800"><p class="font-semibold">{{ t('audioMemoryTest.importantPureAudioTest') }}</p>
                <p class="text-sm mt-1">{{ t('audioMemoryTest.pureAudioTestDesc') }}</p></div>
            </div>
          </div>
          <div class="grid grid-cols-2 gap-4">
            <Button class="py-3" variant="outline" @click="stage = 'familiarize'">{{ t('audioMemoryTest.returnToFamiliarize') }}</Button>
            <Button class="bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white py-3 font-semibold shadow-lg hover:shadow-xl transition-all duration-200"
                    @click="handleStartTest">
              {{ t('audioMemoryTest.startFormalTest') }}
            </Button>
          </div>
        </CardContent>
      </Card>
    </transition>
  </div>

  <!-- Test Stage -->
  <div v-else-if="stage === 'test'" class="max-w-4xl mx-auto space-y-6">
    <div class="flex flex-col sm:flex-row gap-4 items-center justify-between">
      <div class="flex items-center gap-4">
        <Badge class="bg-indigo-100 text-indigo-700 border-indigo-300" variant="outline">{{ t('audioMemoryTest.level') }} {{ currentLevel }} /
          {{ MAX_LEVEL }}
        </Badge>
        <div class="flex items-center gap-2 text-slate-600">
          <Trophy class="w-4 h-4"/>
          <span class="font-semibold">{{ score }} {{ t('audioMemoryTest.points') }}</span></div>
      </div>
      <div class="flex items-center gap-4">
        <div class="flex gap-1">
          <span v-for="i in 3" :key="i"
                :class="['w-3 h-3 rounded-full', i <= lives ? 'bg-red-500' : 'bg-slate-200']"></span>
        </div>
        <span class="text-sm text-slate-600">{{ t('audioMemoryTest.lives') }}</span>
      </div>
    </div>
    <div class="bg-white rounded-lg p-4 border border-slate-200">
      <div class="flex justify-between items-center mb-2">
        <span class="text-sm text-slate-600">{{ t('audioMemoryTest.sequenceLength') }}</span>
        <span class="text-sm font-semibold text-slate-800">{{ sequence.length }} {{ t('audioMemoryTest.notes') }}</span>
      </div>
      <Progress :model-value="(userSequence.length / sequence.length) * 100" class="h-2"/>
    </div>
    <transition name="fade">
      <Card v-if="isPlaying || showingSequence" class="bg-gradient-to-r from-indigo-50 to-purple-50 border-indigo-200">
        <CardContent class="py-4">
          <div class="flex items-center justify-center gap-3">
            <Volume2 class="w-5 h-5 text-indigo-600 animate-pulse"/>
            <span class="text-indigo-800 font-semibold">{{ t('audioMemoryTest.playingSequence') }}</span>
          </div>
          <div class="text-center text-sm text-indigo-600 mt-1">{{ t('audioMemoryTest.noVisualCuesListen') }}</div>
        </CardContent>
      </Card>
    </transition>
    <Card class="bg-white/90 backdrop-blur-sm border-indigo-200 shadow-lg">
      <CardHeader>
        <CardTitle class="text-center">{{ t('audioMemoryTest.clickToRepeat') }}</CardTitle>
        <p class="text-center text-slate-600 text-sm">{{ t('audioMemoryTest.clickInOrder') }}</p>
      </CardHeader>
      <CardContent>
        <div class="grid grid-cols-4 md:grid-cols-7 gap-4 max-w-2xl mx-auto">
          <div v-for="tone in AUDIO_TONES" :key="tone.id">
            <Button :class="['w-16 h-16 rounded-full hover:opacity-80 text-white font-semibold shadow-lg transition-all duration-200', tone.color]" :disabled="isPlaying || showingSequence"
                    @click="handleTestToneClick(tone)">
              {{ tone.name }}
            </Button>
          </div>
        </div>
        <div v-if="userSequence.length > 0" class="mt-6">
          <h3 class="text-sm font-semibold text-slate-600 mb-3 text-center">{{ t('audioMemoryTest.yourInput') }}</h3>
          <div class="flex justify-center gap-2 flex-wrap">
            <div v-for="(tone, index) in userSequence" :key="`${tone.id}-${index}`"
                 :class="['w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-semibold shadow', tone.color]">
              {{ tone.name }}
            </div>
          </div>
        </div>
        <div v-if="audioError" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
          <div class="flex items-center gap-2">
            <VolumeX class="w-4 h-4 text-red-600"/>
            <span class="text-red-800 text-sm">{{ t('audioMemoryTest.audioPlaybackFailed') }}</span></div>
        </div>
        <div v-if="!isPlaying && !showingSequence && sequence.length > 0" class="mt-4 text-center">
          <Button class="text-indigo-600 border-indigo-300 hover:bg-indigo-50" size="sm" variant="outline"
                  @click="playSequence(sequence)">
            <Play class="w-4 h-4 mr-2"/>
            {{ t('audioMemoryTest.replaySequence') }}
          </Button>
        </div>
      </CardContent>
    </Card>
  </div>

  <!-- Results Stage -->
  <div v-else-if="stage === 'results'" class="max-w-2xl mx-auto">
    <transition appear name="fade">
      <Card class="bg-white/90 backdrop-blur-sm border-indigo-200 shadow-xl">
        <CardHeader class="text-center pb-6">
          <div
            class="w-20 h-20 bg-gradient-to-br from-indigo-500 to-purple-500 rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
            <Trophy class="w-10 h-10 text-white"/>
          </div>
          <CardTitle class="text-3xl text-slate-800 mb-2">{{ t('audioMemoryTest.testComplete') }}</CardTitle>
          <div class="text-6xl font-bold bg-gradient-to-r from-indigo-500 to-purple-500 bg-clip-text text-transparent">
            {{ results.finalScore }}
          </div>
          <p class="text-slate-600">{{ t('audioMemoryTest.audioMemoryScore') }}</p>
        </CardHeader>
        <CardContent class="space-y-6">
          <div class="grid grid-cols-2 gap-4">
            <div class="info-box">
              <div class="info-box-title text-indigo-600">{{ currentLevel }}</div>
              <div class="info-box-body">{{ t('audioMemoryTest.levelReached') }}</div>
            </div>
            <div class="info-box">
              <div class="info-box-title text-purple-600">{{ score }}</div>
              <div class="info-box-body">{{ t('audioMemoryTest.totalScore') }}</div>
            </div>
          </div>
          <div class="space-y-3">
            <div class="result-row"><span class="text-slate-600">{{ t('audioMemoryTest.longestSequence') }}</span><span
              class="font-semibold text-slate-800">{{ results.maxSequenceLength }} {{ t('audioMemoryTest.notes') }}</span></div>
            <div class="result-row"><span class="text-slate-600">{{ t('audioMemoryTest.audioMemorySpan') }}</span><span
              class="font-semibold text-slate-800">{{ results.audioMemorySpan }} {{ t('audioMemoryTest.notes') }}</span></div>
            <div class="result-row"><span class="text-slate-600">{{ t('audioMemoryTest.completionRate') }}</span><span
              class="font-semibold text-slate-800">{{ results.accuracyRate }}%</span></div>
            <div class="result-row"><span class="text-slate-600">{{ t('audioMemoryTest.familiarizeClicks') }}</span><span
              class="font-semibold text-slate-800">{{ familiarizeClicks }} {{ t('audioMemoryTest.times') }}</span></div>
          </div>
          <Button class="w-full bg-gradient-to-r from-indigo-500 to-purple-500 hover:from-indigo-600 hover:to-purple-600 text-white py-3 text-lg font-semibold shadow-lg"
                  size="lg"
                  @click="handleComplete">
            查看详细结果
          </Button>
        </CardContent>
      </Card>
    </transition>
  </div>
</template>

<script setup>
import {ref, computed, onMounted, onUnmounted} from 'vue';
import {Volume2, VolumeX, Play, Pause, Clock, Trophy, Star, CheckCircle} from 'lucide-vue-next';
import { useGlobalI18n } from '~/composables/useGlobalI18n';

const { t } = useGlobalI18n();

const emit = defineEmits(['complete']);

// --- Constants ---
const AUDIO_TONES = [
  {id: 1, frequency: 261.63, duration: 500, name: 'Do', color: 'bg-red-500'},
  {id: 2, frequency: 293.66, duration: 500, name: 'Re', color: 'bg-orange-500'},
  {id: 3, frequency: 329.63, duration: 500, name: 'Mi', color: 'bg-yellow-500'},
  {id: 4, frequency: 349.23, duration: 500, name: 'Fa', color: 'bg-green-500'},
  {id: 5, frequency: 392.00, duration: 500, name: 'Sol', color: 'bg-blue-500'},
  {id: 6, frequency: 440.00, duration: 500, name: 'La', color: 'bg-indigo-500'},
  {id: 7, frequency: 493.88, duration: 500, name: 'Si', color: 'bg-purple-500'}
];
const MAX_LEVEL = 10;
const MIN_FAMILIARIZE_CLICKS = 10;

// --- State ---
const stage = ref('instructions'); // 'instructions', 'familiarize', 'ready-check', 'test', 'results'
const currentLevel = ref(1);
const sequence = ref([]);
const userSequence = ref([]);
const isPlaying = ref(false);
const showingSequence = ref(false);
const score = ref(0);
const lives = ref(3);
const audioError = ref('');
const startTime = ref(0);
const familiarizeClicks = ref(0);

let audioContext = null;
let oscillator = null;

// --- Computed Properties ---
const familiarizeProgress = computed(() => Math.min(100, Math.round((familiarizeClicks.value / MIN_FAMILIARIZE_CLICKS) * 100)));
const canStartTest = computed(() => familiarizeClicks.value >= MIN_FAMILIARIZE_CLICKS);
const results = computed(() => {
  const maxPossibleScore = Array.from({length: MAX_LEVEL}, (_, i) => (i + 1) * 10 + (3 * 5)).reduce((a, b) => a + b, 0);
  const finalScore = Math.min(100, Math.round((score.value / maxPossibleScore) * 100));
  return {
    finalScore,
    maxSequenceLength: Math.min(2 + currentLevel.value, 12),
    audioMemorySpan: currentLevel.value > 1 ? currentLevel.value + 1 : 3,
    accuracyRate: currentLevel.value > 1 ? Math.round(((currentLevel.value - 1) / MAX_LEVEL) * 100) : 0,
  };
});

// --- Audio Methods ---
const initializeAudio = async () => {
  try {
    if (!audioContext) {
      audioContext = new (window.AudioContext || window.webkitAudioContext)();
    }
    if (audioContext.state === 'suspended') {
      await audioContext.resume();
    }
    audioError.value = '';
    return true;
  } catch (error) {
    console.error('Audio initialization failed:', error);
    audioError.value = '音频初始化失败，请检查浏览器设置或尝试刷新页面';
    return false;
  }
};

const playTone = async (tone) => {
  if (!audioContext) return;
  return new Promise((resolve) => {
    if (oscillator) {
      try {
        oscillator.stop();
      } catch (e) { /* ignore */
      }
    }
    oscillator = audioContext.createOscillator();
    const gainNode = audioContext.createGain();
    oscillator.connect(gainNode);
    gainNode.connect(audioContext.destination);
    oscillator.frequency.value = tone.frequency;
    oscillator.type = 'sine';
    const now = audioContext.currentTime;
    gainNode.gain.setValueAtTime(0, now);
    gainNode.gain.linearRampToValueAtTime(0.3, now + 0.01);
    gainNode.gain.exponentialRampToValueAtTime(0.01, now + tone.duration / 1000);
    oscillator.start(now);
    oscillator.stop(now + tone.duration / 1000);
    oscillator.onended = resolve;
  });
};

const playSequence = async (seq) => {
  const success = await initializeAudio();
  if (!success) return;

  isPlaying.value = true;
  showingSequence.value = true;

  try {
    await new Promise(resolve => setTimeout(resolve, 1000));
    for (const tone of seq) {
      await playTone(tone);
      await new Promise(resolve => setTimeout(resolve, 400));
    }
  } catch (error) {
    console.error('Failed to play sequence:', error);
    audioError.value = '音频播放失败，请检查音量设置';
  } finally {
    showingSequence.value = false;
    isPlaying.value = false;
  }
};

// --- Event Handlers ---
const handleStartFamiliarize = async () => {
  const success = await initializeAudio();
  if (success) {
    stage.value = 'familiarize';
  }
};

const handleFamiliarizeToneClick = async (tone) => {
  if (isPlaying.value) return;
  await playTone(tone);
  familiarizeClicks.value++;
};

const handleReadyCheck = () => {
  if (canStartTest.value) {
    stage.value = 'ready-check';
  }
};

const handleStartTest = () => {
  stage.value = 'test';
  startTime.value = Date.now();
  const initialSequence = generateSequence(3);
  sequence.value = initialSequence;
  setTimeout(() => playSequence(initialSequence), 1000);
};

const handleTestToneClick = async (tone) => {
  if (isPlaying.value || showingSequence.value) return;

  await playTone(tone);

  const newSeq = [...userSequence.value, tone];
  userSequence.value = newSeq;

  const isCorrect = sequence.value[newSeq.length - 1].id === tone.id;

  if (!isCorrect) {
    lives.value--;
    userSequence.value = [];
    if (lives.value <= 0) {
      stage.value = 'results';
    } else {
      setTimeout(() => playSequence(sequence.value), 1000);
    }
  } else if (newSeq.length === sequence.value.length) {
    const levelScore = currentLevel.value * 10 + (lives.value * 5);
    score.value += levelScore;

    if (currentLevel.value >= MAX_LEVEL) {
      stage.value = 'results';
    } else {
      const nextLevel = currentLevel.value + 1;
      currentLevel.value = nextLevel;
      userSequence.value = [];
      setTimeout(() => {
        const newGeneratedSeq = generateSequence(Math.min(2 + nextLevel, 12));
        sequence.value = newGeneratedSeq;
        playSequence(newGeneratedSeq);
      }, 1500);
    }
  }
};

const handleComplete = () => {
  const res = results.value;
  emit('complete', {
    id: Date.now().toString(),
    testType: 'audio-memory',
    score: res.finalScore,
    completedAt: new Date(),
    duration: startTime.value > 0 ? Math.round((Date.now() - startTime.value) / 1000) : 0,
    details: {
      levelReached: currentLevel.value,
      totalScore: score.value,
      livesRemaining: lives.value,
      sequencesCompleted: currentLevel.value - 1,
      ...res
    }
  });
};

// --- Utility Functions ---
const generateSequence = (length) => {
  const newSequence = [];
  for (let i = 0; i < length; i++) {
    newSequence.push(AUDIO_TONES[Math.floor(Math.random() * AUDIO_TONES.length)]);
  }
  return newSequence;
};

// --- Lifecycle ---
onUnmounted(() => {
  if (oscillator) {
    try {
      oscillator.stop();
    } catch (e) { /* ignore */
    }
  }
  if (audioContext && audioContext.state !== 'closed') {
    audioContext.close();
  }
});

</script>

<style scoped>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

.step-number {
  @apply w-6 h-6 bg-indigo-500 text-white rounded-full flex items-center justify-center text-sm font-semibold flex-shrink-0 mt-0.5;
}

.info-box {
  @apply text-center p-4 bg-gradient-to-br from-indigo-50 to-indigo-100 rounded-xl border border-indigo-200;
}

.info-box-title {
  @apply text-2xl font-bold mb-1;
}

.info-box-body {
  @apply text-sm;
}

.result-row {
  @apply flex justify-between items-center p-3 bg-slate-50 rounded-lg;
}
</style>